﻿using CrawlerApp.Core.Entities;
using CrawlerApp.Infrastructure.Interfaces;
using CrawlerApp.Services.Interfaces;
using Microsoft.Extensions.Configuration;
using Quartz;
using Serilog;
using System;
using System.Linq;
using System.Threading.Tasks;

namespace CrawlerApp.Services.Job
{
    public class TagJob : IJob
    {
        private readonly ILogger logger;
        private readonly IConfiguration configuration;
        private readonly IRepository<Tag> repository;
        private readonly IHtmlPraseService htmlPrase;

        public static event EventHandler SuccessHandler;
        public static event EventHandler FailedHandler;

        const string url = "http://www.zxcs.me/map.html";

        public TagJob(ILogger logger, IConfiguration configuration, IRepository<Tag> repository, IHtmlPraseService htmlPrase)
        {
            this.logger = logger.ForContext<TagJob>();
            this.configuration = configuration;
            this.repository = repository;
            this.htmlPrase = htmlPrase;
        }

        public async Task Execute(IJobExecutionContext context)
        {
            logger.Information("开始采集标签信息");

            var tags = await htmlPrase.GetSpecifyCollectionAsync(url, "//div[@id='tag']/ul/li/a", selector => new Tag(selector.InnerText, selector.Attributes["href"].Value));

            try
            {
                var dbTags = await repository.ToListAsync(onChange: true);

                foreach (var tag in tags)
                {
                    if (dbTags.Any(t => t.Name == tag.Name))
                    {
                        //var newTag = dbTags.SingleOrDefault(t => t.Href != tag.Href || t.Length != tag.Length);
                        //if (newTag != null)
                        //{
                        //    newTag.SetHref(tag.Href).SetLength(tag.Length);
                        //    await repository.UpdateAsync(newTag);
                        //}
                    }
                    else
                    {
                        await repository.AddAsync(tag);
                    }
                }
                SuccessHandler?.Invoke(this, null);
            }
            catch (Exception ex)
            {
                logger.Error(ex, ex.Message);
                FailedHandler?.Invoke(this, null);
            }

            //await new BrowserFetcher(new BrowserFetcherOptions { Host = "https://mirrors.huaweicloud.com" }).DownloadAsync(BrowserFetcher.DefaultRevision);

            //using (var browser = await Puppeteer.LaunchAsync(new LaunchOptions { Headless = true }))
            //{
            //    using (var page = await browser.NewPageAsync())
            //    {
            //        try
            //        {
            //            await page.GoToAsync(url);
            //            var jsSelector = @"Array.from(document.querySelectorAll('#tags li a')).map(a=>{return {name:a.text,href:a.href}})";
            //            var tags = await page.EvaluateExpressionAsync<IReadOnlyCollection<Tag>>(jsSelector);

            //            var dbTags = await repository.ToListAsync();

            //            foreach (var tag in tags.Where(c => !string.IsNullOrWhiteSpace(c.Name)))
            //            {
            //                // 添加
            //                if (!dbTags.Any(c => c.Name == tag.Name))
            //                {
            //                    await repository.AddAsync(tag);
            //                }
            //                else
            //                {
            //                    var dbTag = dbTags.SingleOrDefault(c => c.Name == tag.Name && (c.Length != tag.Length || c.Href != tag.Href));
            //                    if (dbTag != null) // 更新
            //                    {
            //                        dbTag
            //                            .SetLength(tag.Length)
            //                            .SetHref(tag.Href);
            //                        await repository.UpdateAsync(dbTag);
            //                    }
            //                }
            //            }
            //            SuccessHandler?.Invoke(this, null);
            //        }
            //        catch(PuppeteerException ex)
            //        {
            //            logger.Error(ex, ex.Message);
            //            FailedHandler?.Invoke(this, null);
            //        }
            //    }
            //}
            logger.Information("标签信息采集完成");
        }
    }
}
